# -*- coding: utf-8 -*-
from PySide2 import QtWidgets 

import maya.cmds as mc

import maya.mel as mel
import os, glob, math, re
import DH_PySideUidata
import pymel.core as pm

form_class, base_class = DH_PySideUidata.loadUiType(r'Y:\Reference\TD\maya2017\XCM_tools\othertools\XCM_sceneCleaner.ui')


class DH_ZSZR_sceneCleaner(base_class, form_class):

    def __init__(self):
        self.window_name = 'DH_ZSZR_sceneCleaner'
        if mc.window(self.window_name, exists=True):
            mc.deleteUI(self.window_name)
        super(DH_ZSZR_sceneCleaner, self).__init__(parent=DH_PySideUidata.getMayaWindow())
        self.setupUi(self)
        desktop = QtWidgets.QApplication.desktop().availableGeometry()
        size = self.geometry()
        self.move((desktop.width()-size.width())/2, (desktop.height()-size.height())/2)
        
        self.progressBar.setValue(0)

        self.cam_name_checker.clicked.connect(self.check_camname)
        self.fps_checker.clicked.connect(self.fps_check)
        self.referencEditor_checker.clicked.connect(self.check_namespace)
        self.high_model_cheker.clicked.connect(self.check_H_model)
        self.displayLayer_checker.clicked.connect(self.checkDisplayLayer)
        self.filename_checker.clicked.connect(self.check_filename_name)
        self.anim_start_checker.clicked.connect(self.check_start_frame)
        #self.AD_checker.clicked.connect(self.AD_scene_check)
        self.apply_all.clicked.connect(self.applyAll)
        self.save_file.clicked.connect(self.standard_saving)

   
    def resultOutput(self,content):# output the result of cleaning
        self.result_output.setFontPointSize(12)
        current_content = self.result_output.toPlainText()
        self.result_output.setText(current_content+content)
        # self.result_output.setFontPointSize(12)
        
    def setColorGreen(self,whitch_button):# set the right option button color to green
        whitch_button.setStyleSheet("background-color: rgb(56, 113, 0);")
        
    def erroroutput(self,errorContent):# show the dialogue of error
        mc.confirmDialog(title=u'提示', message=errorContent, button=['ok'])
        
    def check_camname(self):# check cameraname
        cam_name = mc.ls(type = 'camera')[0]
        # self.resultOutput(cam_name)
        if not re.search("StereoCamCenterCamShape",cam_name):
            self.resultOutput(u"1.未发现相机，请检查！\n")
        # if mc.objExists("::*StereoCamCenterCamShape*"):
            # logging.error(u"发现多个3D相机！请检查")
            return False

        whitch_shot = mc.file(q=1,sn=1,shn=1)
        camName = "AN_" +  "*" +"_"+"*" +"_"+ "StereoCamCenterCamShape"
        #print camName
        if mc.objExists(camName):
            #mc.select("*"+camName+"*",r=1)
            selA = mc.ls(camName,type = "camera")
            # self.resultOutput(selA[0])
            if len(selA) < 3:
                # print selA
                if mc.objExists("*::*"+camName) or mc.objExists("*:*"+camName):
                    remove_cam = mc.ls("*::*"+camName) + mc.ls("*:*"+camName)
                    self.resultOutput(u"1.存在引用状态的3D相机！请先移除..\n%s\n"%remove_cam[0])
                    return False
                    
                chek3D = mc.confirmDialog(title='Confirm', message=u"请检查成像面是否正确", button=['ok',u"已检查，无误"])
                self.setColorGreen(self.cam_name_checker)
                self.resultOutput(u"1.相机名为%s，符合规范.\n"%selA[0])
                return True
            else:
                #print selA
                #pass
                #self.erroroutput(u"存在多个相机！\n%s\n请检查."%selA) 
                self.resultOutput(u"1.可能存在多个相机！\n%s\n"%selA)
                return 
        else:
            #self.erroroutput(u"相机不存在！请检查.") 
            self.resultOutput(u"1.检查相机名发生错误！相机可能不存在或者命名不对.\n")
            return 
               
    def fps_check(self):# check whether the fps is right or not 
        fpsString = mc.currentUnit(query=True,t=True)
        if fpsString == 'film':
            self.setColorGreen(self.fps_checker)
            self.resultOutput(u"2.fps为24，符合规范.\n")
            return True
        else:
            self.resultOutput(u"2.检查fps发生错误！\n")
            #self.erroroutput(u"fps不正确！请检查.")
            return 
            
            
    def check_namespace(self):
        invalid_no_namespace = []
        invalid_more_namespace = []
        invalid_namspace = []
        for ref in mc.ls(references=True):            
            try:
                filename = mc.referenceQuery(ref, filename=1)
                ns = mc.referenceQuery(ref, ns=1, shn=1)
                code = os.path.basename(filename).split("_")[0]
                nodes = mc.referenceQuery(ref,n=1)
                nodes = list(set([k.rpartition(":")[0] for k in nodes]))    
                if [k for k in nodes if ":" in k]:
                    invalid_more_namespace.extend(nodes)
                if not ns:
                    invalid_no_namespace.append(filename)
                if ":" in ns:
                    invalid_more_namespace.append(ns)    
                if "_" in ns:
                    invalid_namspace.append(ns)
                    
                if not re.search(code, ns):
                    invalid_namspace.append(ns)                    
            except:
                continue
        
        noloadref = [j for j in mc.file(q=1,r=1) if not mc.referenceQuery(j, il=1) and not re.search("_L_",j)]
        if noloadref:
            self.resultOutput(u"3.可能存在以下未勾选的reference,请打开referenceEditor自行检查，若无问题请忽略此项。\n {0}\n".format(noloadref))
        # if invalid_no_namespace:
            # self.resultOutput(u"3.请打开referenceEditor，reference 不带 namespace {0}\n".format(invalid_no_namespace))
            # return
        #if invalid_more_namespace:
            #self.resultOutput(u"3.请打开referenceEditor，reference 多层 namespace {0}\n".format(invalid_more_namespace))
            #return            
        #if invalid_namspace:
            #self.resultOutput(u"3.请打开referenceEditor，reference namespace {0} 有问题,请检查\n".format(invalid_namspace))
            #return
        if not (invalid_no_namespace and invalid_more_namespace and invalid_namspace):
            checkPath = self.check_reference_path()
            if checkPath:
                self.resultOutput(u"3.reference检查完毕，符合规范.但请打开referenceEditor确保已经将所有代理移除。\n")
                self.erroroutput(u"请在ReferenceEditor中检查是否还存在代理（两个方块符号），若有，请移除")
                mel.eval("ReferenceEditor")
                self.setColorGreen(self.referencEditor_checker)
        return True
    
    def check_reference_path(self):
        invalid = []        
        for ref in mc.ls(references=True):   
            try:
                if mc.referenceQuery(ref , il=1):
                    filename = mc.referenceQuery(ref, filename=1)
                    search = re.search("Y:/XCM_2019DY/Asset/seq000", filename)
                    if not search:
                        invalid.append(filename)
            except:
                continue
        if invalid:
            self.resultOutput(u"3.引用目录错误，只允许在 Y:\XCM_2019DY\Asset\seq000, 请检查 {0}\n".format(invalid))
            return
        return True
    
    def check_H_model(self):#autoSwitch proxy to high
        loadref = [j for j in mc.file(q=1,r=1) if mc.referenceQuery(j, il=1)]
        proxyref = [i for i in loadref if "_B_" in i]
        if proxyref:
            self.resultOutput(u"4.存在未切换成高模的文件！ {0}\n".format(proxyref))
            return False
        self.resultOutput(u"4.不存在未切换成高模的文件\n")
        self.setColorGreen(self.high_model_cheker)
        return True

    def checkDisplayLayer(self):
        error_layers = []
        allow_layer = ["norender","NoRender"]
        error_layers.extend([k for k in [k for k in mc.ls(type="displayLayer") if k!="defaultLayer"] if k not in allow_layer])
        error_layers = [k.encode('utf-8') for k in error_layers if not mc.referenceQuery(k,inr=1)]
        print error_layers
        moveObj = self.moveThingsToNorender()
        self.resultOutput(u"5.已将自建物体{0}移动到{1};\n".format(moveObj[0],moveObj[1]))
        if error_layers:
            mc.delete(error_layers)
            self.resultOutput(u"发现有自建层，已删除 {0}(允许的自建层名为“norender”或者“NoRender”)\n".format(error_layers))
            self.erroroutput(u"发现有自建物体%s，请确保都已经替换为正确的资产..."%moveObj[0])
            self.setColorGreen(self.displayLayer_checker)
            return True
        else:
            self.resultOutput(u"未发现自建显示层;\n")
            self.setColorGreen(self.displayLayer_checker)
        return True
    def moveThingsToNorender(self):
        selfBiultObj = \
        pm.ls( "*",type = "mesh")+\
        pm.ls( "*",type = "nurbsCurve")+\
        pm.ls( "*",type = "stroke")
        objName = list()
        if selfBiultObj :
            objName = [j for j in selfBiultObj if pm.referenceQuery(j,inr = True) == False]
            # self.erroroutput(u"发现有自建物体%s，请确保都已经替换为正确的资产..."%objName)
        layerName=""
        # pm.editDisplayLayerMembers(layerName,selfBiultObj,noRecurse = True)
        if mc.objExists("norender"):
            layerName="norender"
        elif mc.objExists("NoRender"):
            layerName="NoRender"
        else:
            pm.createDisplayLayer(name="NoRender",number=1,empty=True)
            layerName = "NoRender"
        pm.editDisplayLayerMembers(layerName,objName,noRecurse = True)
        self.deleteUnknownNodes()
        return objName,layerName

    def deleteUnknownNodes(self):
        if mc.objExists('playBlastNode'):
            mc.delete('playBlastNode')
        if mc.objExists('frameExp*'):
            mc.delete('frameExp*')
        for node in mc.unknownPlugin(q=True, l=True):
            try:
                mc.unknownPlugin(node, r=True)
            except:
                pass
    def check_frame_range(self):
        filename = mc.file(q=1,sn=1).split("/")[-1]
        file_frame_range = re.split('[()]',filename)[-2].split("-")
        # min_frame = str(mc.playbackOptions(ast=True, query=True))
        max_frame = mc.playbackOptions(aet=True, query=True)
        mc.playbackOptions(minTime=101)
        mc.playbackOptions(ast=101)
        mc.playbackOptions(maxTime = max_frame)
        if "101" == file_frame_range[0] and str(int(max_frame)) == file_frame_range[1]:
            return True
        else:
            logging.error("当前帧数范围和文件名中的帧数范围不一致！请检查！")
            return False

    def check_filename_name(self):
        if not self.check_frame_range():
            return
        filename = mc.file(q=1,sn=1).split("/")[-1]
        min_frame = str(int(mc.playbackOptions(ast=True, query=True)))
        max_frame = str(int(mc.playbackOptions(aet=True, query=True)))
        # prefix = 'XCM_2019DY_seq\d{3}_sc\d{3}'
        # print filename
        a = re.match(("XCM_2019DY_seq\d{3}_sc\d{3}_(an|bk|ly)"+"\("+min_frame+"-"+max_frame+"\)"+".ma"),filename)
        # print not a
        b = re.match(("XCM_2019DY_seq\d{3}_sc\d{3}[A-Z]_(an|bk|ly)"+"\("+min_frame+"-"+max_frame+"\)"+".ma"),filename)
        # print not b
        if not (a or b):
            # self.resultOutput(u"6.文件名符合规范%s\n"%filename)
            # self.setColorGreen(self.filename_checker) 
            # return True
            self.resultOutput(u"6.文件命名不符合规范!请修改.\n")
            return
        else:
            self.resultOutput(u"6.文件名符合规范%s\n"%filename)
            self.setColorGreen(self.filename_checker) 
            return True
            
    def check_start_frame(self):
        start_frame = mc.playbackOptions(minTime=True, query=True)
        min_frame = mc.playbackOptions(ast=True, query=True)
        end_frame = mc.playbackOptions(maxTime=True, query=True)
        max_frame = mc.playbackOptions(aet=True, query=True)
        if not (start_frame == min_frame == 101 and end_frame == max_frame):
            mc.playbackOptions(minTime=101)
            mc.playbackOptions(ast=101)
            mc.playbackOptions(maxTime = max_frame)
            self.resultOutput(u"7.发现时间滑块未拉满或动画未从100f开始！已修正.\n")
            self.setColorGreen(self.anim_start_checker) 
        else:
            self.resultOutput(u"7.时间滑块正常，符合规范.\n")
            self.setColorGreen(self.anim_start_checker)
        return True
    
    '''
    def AD_scene_check(self):
        all_ad = mc.ls(r"*E*SH*_SC*_AD_AR*")
        extra_ad = []
        if len(all_ad) > 1 or len(all_ad) == 0:
            for eachad in  all_ad:
                if not mc.listRelatives(eachad,c=1):
                    extra_ad.append(eachad)
                    mc.delete(eachad)
            if extra_ad:
                self.resultOutput(u"8.已删除多余的场景AD文件%s\n"%extra_ad)
            leftAD = mc.ls(r"*E*SH*_SC*_AD_AR*")
            if not len(leftAD) == 1:
                self.resultOutput(u"8.不存在场景AD文件或者多余的场景文件未处理！\n")
                return
            self.setColorGreen(self.AD_checker)
            return True
        else:
            self.resultOutput(u"8.场景中只存在一个AD文件%s，符合规范\n"%all_ad[0]) 
            self.setColorGreen(self.AD_checker)
            return True
        '''
    def list_all_windows(self):
        all_windows = mc.lsUI(typ = 'window')
        window_remove = ['MayaWindow','DH_ZSZR_sceneCleaner']
        for  _ in window_remove:
            if mc.window(_,exists=True):
                all_windows.remove(_)
        return all_windows

    def applyAll(self):
        checkNumber = 0

        if not self.check_camname():
            checkNumber+=1
        self.progressBar.setValue(14)
        if not  self.fps_check():
            checkNumber+=1
        self.progressBar.setValue(28)
        if not  self.check_namespace():
            checkNumber+=1
        self.progressBar.setValue(42)
        if not  self.check_H_model():
            checkNumber+=1
        self.progressBar.setValue(56)
        if not  self.checkDisplayLayer():
            checkNumber+=1
        self.progressBar.setValue(70)
        if not  self.check_start_frame():
            checkNumber+=1
        self.progressBar.setValue(84)
        if not  self.check_filename_name():
            checkNumber+=1
        #if not  self.AD_scene_check():
            #checkNumber+=1
        self.progressBar.setValue(100)
        # print checkNumber
        return checkNumber

    def saving_action(self):
        mc.deleteUI(self.list_all_windows())
        mel.eval("source \"Y:/OldFile/X_Projects/DHTool/set_wareframe.mel\";")
        mc.file(save =1)

    def standard_saving(self):
        ifchecked = mc.confirmDialog(title='Confirm', message=u"确保已经通过所有检查项？", button=[u'稍等，忘了检查了丿囧',u"已检查，放心吧！"])
        if ifchecked == u"已检查，放心吧！":
            self.saving_action()
            self.resultOutput(u"\n检查完成，均已符合规范，已自动保存文件.\n")
            return True
        else:
             return False
  
if __name__ == '__main__':
    DH_ZSZR_sceneCleaner().show()      








